using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Xml;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
using ViewOn.Kernel;
using ViewOn.Helper.WPF;
using ViewOnCore.Helper.WPF;
using ViewOn.UI.Control;
using ViewOn.UI.Dialog;
using ViewOn.AddIns;
using ViewOn.AddInsHostContract;
using ViewOn.AddInsHostContract.Media;
using ViewOn.AddInsHostContract.Visual;
using ViewOnCore;
using ViewOnCore.HostContract.Media;
using ViewOnCore.HostContract;
using ViewOnCore.Device;
using ViewOnCore.Visual;

namespace ViewOn.UI.VisualModeContainer
{

    public partial class NormalViewModeContainer : System.Windows.Controls.UserControl, IVisualModeContainer
    {

        #region Variables

        //---- Expand / Collapse
        private bool _isExpanded = true;
        private double collapseHeight = -1;

        #endregion

        #region Constructor

        public NormalViewModeContainer()
        {
            //---- Initialize
            InitializeComponent();

            //---- Skin window events
            skinWindow.SwicthToMiniPlayer += new EventHandler(skinWindow_SwicthToMiniPlayer);
            skinWindow.SettingsButtonClik += new EventHandler(skinWindow_SettingsButtonClik);

            //---- Device events
            Host.MediaService.MediaDeviceActivation += new EventHandler(MediaService_MediaDeviceActivation);

            Host.MediaService.MediaDeviceOperation += new MediaDeviceOperationEventHandler(MediaService_MediaDeviceOperation);

            ((VisualService)Host.VisualService).NavigateToRequest += new EventHandler(NormalViewModeContainer_NavigateToRequest);
            ((VisualService)Host.VisualService).NavigateBackRequest += new EventHandler(NormalViewModeContainer_NavigateBackRequest);

            //---- Navigation
            navigationFrame.OnNavigationCompleted += new NavigationPanelHandler(navigationFrame_OnNavigationCompleted);
            navigationFrame.OnNavigationStarted += new NavigationPanelHandler(navigationFrame_OnNavigationStarted);

            this.Loaded += new RoutedEventHandler(Container_Loaded);
        }

        void Container_Loaded(object sender, RoutedEventArgs e)
        {
            //---- Remove the event, to avoid recalling it (Due to mini player manipulation)
            this.Loaded -= new RoutedEventHandler(Container_Loaded);

            SelectDefaultDevice();

            Dispatcher.Invoke(DispatcherPriority.Normal,
                (DelegateInvoker)delegate { MediaKernel.OnUIInitialized(); });
        }

        #endregion

        #region SelectDefaultDevice

        private void SelectDefaultDevice()
        {
            foreach (MediaDeviceControl control in navigationPanel.Children)
                if (control.MediaDevice == Host.MediaService.CurrentMediaDevice)
                    foreach (TreeViewItem item in control.tvDevices.Items)
                        if (item.Tag == Host.MediaService.CurrentMediaDeviceFeature)
                        {
                            item.IsSelected = true;
                            return;
                        }
        }

        #endregion

        #region Implements : IViewModeContainer

        public void ChangeVisualPart(VisualPart visualPart)
        {
            Navigate(visualPart);
        }

        #endregion

        #region skinWindow_SwicthToMiniPlayer

        void skinWindow_SwicthToMiniPlayer(object sender, EventArgs e)
        {
            //---- Change the view mode
            Host.VisualService.VisualPartMode = VisualPartMode.Mini;
        }

        #endregion

        #region Settings

        void skinWindow_SettingsButtonClik(object sender, EventArgs e)
        {
            Host.VisualService.NavigateTo("ViewOnTv_Settings");
        }

        #endregion

        #region Events : MediaService : MediaDeviceActivation

        void MediaService_MediaDeviceActivation(object sender, EventArgs e)
        {
            //---- Choose which Visual Add in must be displayed
            ChooseCurrentVisualPart();
            //if (!ChooseCurrentVisualPart())
            //    return;

            //---- Do the visual modification
            Dispatcher.Invoke(DispatcherPriority.Normal,
                    (DelegateInvoker)delegate { AsyncMediaDeviceActivation(); });
        }

        private bool ChooseCurrentVisualPart()
        {
            //---- Change the Visual Part
            VisualPartPriority currentPriority = VisualPartPriority.None;
            VisualPart currentVisualPart = null;
            foreach (VisualPart visualPart in Host.VisualService.VisualParts)
            {
                if (visualPart.Mode != VisualPartMode.Normal)
                    continue;

                VisualPartPriority priority = visualPart.OnRequestVisualPartPriority();

                if (priority > currentPriority)
                {
                    currentPriority = priority;
                    currentVisualPart = visualPart;
                }
            }

            if (CurrentVisualPart != null && currentVisualPart != null && currentVisualPart.Handle == CurrentVisualPart.Handle)
                return false;

            if (currentVisualPart != null)
            {
                Host.VisualService.UnactiveVisualPart();
                currentVisualPart.IsActive = true;

                return true;
            }

            return false;
        }

        private VisualPart CurrentVisualPart
        {
            get
            {
                foreach (VisualPart visualPart in Host.VisualService.VisualParts)
                    if (visualPart.IsActive)
                        return visualPart;

                return null;
            }
        }

        void AsyncMediaDeviceActivation()
        {
            //---- Mini mode or not ?
            skinWindow.IsMiniModeEnabled = Host.MediaService.CurrentMediaDeviceFeature.IsMiniModeSupported;

            //---- Update the top bar
            if (Host.MediaService.CurrentMediaDeviceFeature.IsDirectPlaySupported)
                ExpandTopBar();
            else
                CollapseTopBar();
        }

        void CollapseTopBar()
        {
            if (!_isExpanded)
            {
                topBarAnimation_Completed(null, null);
                return;
            }
            _isExpanded = false;

            collapseHeight = griMain.RowDefinitions[0].ActualHeight;

            GridLengthAnimation gla = new GridLengthAnimation(GridUnitType.Pixel);
            gla.Completed += new EventHandler(topBarAnimation_Completed);
            gla.From = new GridLength(collapseHeight, GridUnitType.Pixel);
            gla.To = new GridLength(0, GridUnitType.Pixel); ;
            gla.Duration = new TimeSpan(0, 0, 0, 0, 400);
            griMain.RowDefinitions[0].BeginAnimation(RowDefinition.HeightProperty, gla);
        }

        void ExpandTopBar()
        {
            if (_isExpanded)
            {
                topBarAnimation_Completed(null, null);
                return;
            }
            _isExpanded = true;

            GridLengthAnimation gla = new GridLengthAnimation(GridUnitType.Pixel);
            gla.Completed += new EventHandler(topBarAnimation_Completed);
            gla.From = new GridLength(0, GridUnitType.Pixel);
            gla.To = new GridLength(collapseHeight, GridUnitType.Pixel); ;
            gla.Duration = new TimeSpan(0, 0, 0, 0, 400);
            griMain.RowDefinitions[0].BeginAnimation(RowDefinition.HeightProperty, gla);
        }

        void topBarAnimation_Completed(object sender, EventArgs e)
        {
            //---- Change the Visual add in
            VisualPart currentVisualAddIn = CurrentVisualPart;
            if (currentVisualAddIn != null)
            {
                Host.VisualService.UnactiveVisualPart();
                currentVisualAddIn.IsActive = true;
                Navigate(currentVisualAddIn);
            }
        }

        #endregion

        #region Events : MediaService : MediaDeviceOperation

        void MediaService_MediaDeviceOperation(MediaOperationKind operationKind, MediaDevice device)
        {
            if (operationKind == MediaOperationKind.Added)
                OnMediaDeviceAdded(device);
            else if (operationKind == MediaOperationKind.Removed)
                OnMediaDeviceRemoved(device);
        }

        void OnMediaDeviceRemoved(MediaDevice device)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        (DelegateInvoker)delegate { AsyncMediaDeviceRemoved(device); });
        }

        void AsyncMediaDeviceRemoved(MediaDevice device)
        {
            //---- Activate the default device/feature
            Host.MediaService.ActivateMediaDevice(null, null, null);

            //---- Remove this device
            foreach (MediaDeviceControl control in navigationPanel.Children)
                if (control.MediaDevice == device)
                {
                    navigationPanel.Children.Remove(control);
                    return;
                }
        }

        void OnMediaDeviceAdded(MediaDevice device)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        (DelegateInvoker)delegate { AsyncMediaDeviceAdded(device); });
        }

        void AsyncMediaDeviceAdded(MediaDevice device)
        {
            MediaDeviceControl control = new MediaDeviceControl(device);
            int index = Host.MediaService.MediaDevices.IndexOf(device);
            navigationPanel.Children.Insert(index, control);
        }

        #endregion

        #region Navigate

        void NormalViewModeContainer_NavigateBackRequest(object sender, EventArgs e)
        {
            navigationFrame.NavigateBack();
        }

        void NormalViewModeContainer_NavigateToRequest(object sender, EventArgs e)
        {
            string addInHandle = (string)sender;

            foreach (VisualPart addIn in Host.VisualService.VisualParts)
                if (addIn.Handle == addInHandle)
                {
                    Navigate(addIn);
                    return;
                }
        }

        private void Navigate(VisualPart addIn)
        {
            //---- Notify it is hidden
            if (navigationFrame.CurrentElement != null && navigationFrame.CurrentElement != addIn)
                ((VisualPart)navigationFrame.CurrentElement).OnPreHide(this);

            //---- Add the add-in if not already in
            if (!navigationFrame.Elements.Contains((FrameworkElement)addIn))
                navigationFrame.AddUIElement(addIn.Handle, (FrameworkElement)addIn);

            //---- Navigate
            navigationFrame.Navigate((FrameworkElement)addIn);
        }

        #endregion

        #region Sliding events

        void navigationFrame_OnNavigationStarted(FrameworkElement element)
        {
            VisualPart visualAddIn = element as VisualPart;
            visualAddIn.OnPreDisplay(this);
        }

        void navigationFrame_OnNavigationCompleted(FrameworkElement element)
        {
            VisualPart visualAddIn = element as VisualPart;
            visualAddIn.OnPostDisplay(this);
        }

        #endregion

    }

}